<template>
  <div id="app">
    <div id="container" ref="container" @mousedown="onMouseDown">
      <canvas ref="canvas"></canvas>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      image: new Image(),
      viewport: {
        x: 0,
        y: 0,
        width: 414,
        height: 414,
      },
      isDragging: false,
      dragStart: { x: 0, y: 0 },
    };
  },
  mounted() {
    const container = this.$refs.container;
    const canvas = this.$refs.canvas;
    const ctx = canvas.getContext('2d');

    // Set canvas size to match the container size
    canvas.width = container.clientWidth;
    canvas.height = container.clientHeight;

    // Load the image
    this.image.src = 'https://via.placeholder.com/3000x2000'; // Replace with your image URL
    this.image.onload = () => {
      this.drawViewport();
    };

    // Add global event listeners for mouse events
    window.addEventListener('mousemove', this.onMouseMove);
    window.addEventListener('mouseup', this.onMouseUp);
  },
  beforeDestroy() {
    // Remove global event listeners
    window.removeEventListener('mousemove', this.onMouseMove);
    window.removeEventListener('mouseup', this.onMouseUp);
  },
  methods: {
    drawViewport() {
      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');

      // Clear canvas
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Calculate the source rectangle on the image
      const srcX =
        -(this.viewport.x / canvas.width) * this.image.width + canvas.width / 2;
      const srcY =
        -(this.viewport.y / canvas.height) * this.image.height +
        canvas.height / 2;
      const srcWidth = (this.viewport.width / canvas.width) * this.image.width;
      const srcHeight =
        (this.viewport.height / canvas.height) * this.image.height;

      // Ensure the source rectangle is within the image bounds
      const actualSrcX = Math.max(
        0,
        Math.min(srcX, this.image.width - srcWidth)
      );
      const actualSrcY = Math.max(
        0,
        Math.min(srcY, this.image.height - srcHeight)
      );

      // Draw the portion of the image onto the canvas
      ctx.drawImage(
        this.image,
        actualSrcX,
        actualSrcY,
        srcWidth,
        srcHeight,
        0,
        0,
        canvas.width,
        canvas.height
      );
    },
    onMouseDown(event) {
      const container = this.$refs.container;
      this.isDragging = true;
      this.dragStart.x = event.clientX - this.viewport.x;
      this.dragStart.y = event.clientY - this.viewport.y;
    },
    onMouseMove(event) {
      if (this.isDragging) {
        this.viewport.x = event.clientX - this.dragStart.x;
        this.viewport.y = event.clientY - this.dragStart.y;

        // Constrain the viewport to stay within the image bounds
        const canvas = this.$refs.canvas;
        const maxX = this.image.width - canvas.width;
        const maxY = this.image.height - canvas.height;

        this.viewport.x = Math.max(0, Math.min(this.viewport.x, maxX));
        this.viewport.y = Math.max(0, Math.min(this.viewport.y, maxY));

        this.drawViewport();
      }
    },
    onMouseUp() {
      this.isDragging = false;
    },
  },
};
</script>

<style>
#container {
  width: 414px;
  height: 414px;
  position: relative;
  border: 1px solid black;
  overflow: hidden;
}
canvas {
  display: block;
}
</style>
